home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.3d26 source / tn3270 tools / keymap.c < prev    next >
C/C++ Source or Header  |  1991-01-21  |  37KB  |  1,712 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.3d21, January 17, 1991
  5.  *  Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #include <QuickDraw.h>
  34. #include <Menus.h>
  35. #include <Dialogs.h>
  36. #include <Memory.h>
  37. #include <SegLoad.h>
  38. #include <Events.h>
  39. #include <TextEdit.h>
  40. #include <ToolUtils.h>
  41. #include <Desk.h>
  42. #include <Windows.h>
  43. #include <Fonts.h>
  44. #include <Files.h>
  45. #include <Devices.h>
  46. #include <Serial.h>
  47. #include <Resources.h>
  48. #include <Packages.h>
  49. #include <Errors.h>
  50.  
  51.  
  52. #define    NMENUS        3        /* number of defined menus */
  53. #define appleMenu    256
  54. #define    fileMenu    257
  55. #define editMenu    258
  56. #define fileMSize    6        /* size of File menu */
  57.  
  58. #define DEFAULTNUM    129        /* default resource number */
  59.  
  60. typedef struct hexinfo {
  61.     unsigned char *hexname;
  62.     unsigned char hexvalue;
  63.     } hexinfo;
  64.     
  65. typedef struct hexmap {
  66.     unsigned short offset;
  67.     unsigned char stdchar;
  68.     unsigned char aplchar;
  69.     } hexmap;
  70.  
  71. char done;                    /* true to exit program */
  72.                             /* screen control rectangles */
  73.                             /* variables for my window */
  74. MenuHandle myMenus[NMENUS];
  75. struct EventRecord myEvent;
  76. char da_menu;
  77. Rect screenRect;            /* rectangle defining screen */
  78. Rect dragRect;                /* rectangle defining bounds for dragging */
  79. Rect sizeRect;                /* rectangle for resizing windows */
  80. struct Point sfgpoint;        /* standard file dialog locations */
  81. struct Point sfppoint;
  82.  
  83. char defok;                        /* true if good definition read */
  84. unsigned char mapname[64];        /* name of this mapping */
  85. short mapnum;                    /* resource number to use */
  86. SFReply defreply;                /* info. for definition file */
  87. short myresfile;                /* resource file for this program */
  88. short hexcount;                    /* number of entries used in hexbuff */
  89.  
  90. unsigned char keybuffn[128];    /* arrays output to resource in this order */
  91. unsigned char keybuffs[128];
  92. unsigned char keybuffc[128];
  93. unsigned char keybuffcs[128];
  94. unsigned char keybuffo[128];
  95. unsigned char ascbuffn[256];
  96. unsigned char ascbuffs[256];
  97. unsigned char ascbuffc[256];
  98. unsigned char ascbuffcs[256];
  99. unsigned char ascbuffo[256];
  100. hexmap hexbuff[256];
  101.  
  102. main()
  103. {
  104. OSErr rc;
  105.  
  106. macinit();                    /* initialize Mac */
  107. done = 0;
  108. defok = 0;
  109. while (!done) hndmac();        /* handle Mac events and I/O */
  110. macend();
  111. }
  112.  
  113. macinit()
  114. {
  115. short i, bigscreen;
  116.  
  117.             /* set-up general Macintosh environment */
  118. myresfile = CurResFile();
  119. MaxApplZone();                /* set-up for efficient storage use */
  120. for (i=0; i < 4; i++) MoreMasters();
  121. InitGraf(&qd.thePort);
  122. FlushEvents(everyEvent, 0);
  123. InitWindows();
  124. InitFonts();
  125. InitMenus();
  126. InitDialogs(0L);
  127. InitCursor();
  128. TEInit();
  129.  
  130.             /* set-up menus */
  131. for (i=0; i < NMENUS; i++) {
  132.     myMenus[i] = GetMenu(256+i);
  133.     InsertMenu(myMenus[i], 0);
  134.     }
  135. AddResMenu(myMenus[0], 'DRVR');    
  136. da_menu = 0;
  137. appl_menu();
  138.  
  139.             /* center alerts */
  140. ctralrt(256);
  141. ctralrt(260);
  142.  
  143. screenRect = qd.screenBits.bounds;
  144.  
  145. bigscreen = (((screenRect.bottom-screenRect.top) >= 480) &&
  146.              ((screenRect.right-screenRect.left) >= 640)); 
  147.  
  148.             /* calculate standard file dialog location*/
  149. sfppoint.h = (screenRect.right-screenRect.left-304)/2;
  150. sfgpoint.h = (screenRect.right-screenRect.left-348)/2;
  151. if (bigscreen) {
  152.     sfppoint.v = (screenRect.bottom-screenRect.top-184)/3;
  153.     sfgpoint.v = (screenRect.bottom-screenRect.top-200)/3;
  154.     }
  155. else {
  156.     sfppoint.v = (screenRect.bottom-screenRect.top-184)/2;
  157.     sfgpoint.v = (screenRect.bottom-screenRect.top-200)/2;
  158.     }
  159.  
  160. SetRect(&dragRect, 0, 24, screenRect.right-4, screenRect.bottom-4);
  161.  
  162. SetRect(&sizeRect, 50, 25, screenRect.right+1, screenRect.bottom+1);
  163. }
  164.  
  165. macend()
  166. {
  167. }
  168.  
  169. hndmac()
  170. {
  171. OSErr rc;
  172. short code;
  173. GrafPtr gp;
  174. unsigned short h, w;
  175. long l;
  176. struct WindowRecord * whichWindow, * fw;
  177. char frontda;
  178.  
  179. rc = GetNextEvent(everyEvent, &myEvent);
  180. if (rc == 0)                        /* FALSE from GNE */
  181.     switch(myEvent.what) {
  182.         case nullEvent:
  183.                 fw = (WindowRecord *)FrontWindow();
  184.                 frontda = fw->windowKind < 0;
  185.                 if (frontda) {
  186.                     if (!da_menu) {
  187.                         da_menu = 1;
  188.                         SetItem(myMenus[1], fileMSize, "Close");
  189.                         appl_menu();
  190.                         }
  191.                     }
  192.                 else {
  193.                     if (da_menu) {
  194.                         da_menu = 0;
  195.                         SetItem(myMenus[1], fileMSize, "Quit");
  196.                         appl_menu();
  197.                         }
  198.                     }
  199.                 SystemTask();    /* run DAs, etc. */
  200.                 break;
  201.         default:
  202.                 return;
  203.         }
  204. else switch(myEvent.what) {            /* TRUE from GNE */
  205.         case mouseDown:
  206.             code = FindWindow(&myEvent.where, &whichWindow);
  207.             switch (code) {
  208.             case inMenuBar:
  209.                 menu_upd();
  210.                 docommand(MenuSelect(&myEvent.where));
  211.                 break;
  212.             case inSysWindow:
  213.                 SystemClick(&myEvent, whichWindow);
  214.                 break;
  215.             case inDrag:
  216.                 if (whichWindow == FrontWindow())
  217.                     DragWindow(whichWindow, &myEvent.where,
  218.                                 &dragRect);
  219.                 else SelectWindow(whichWindow);
  220.                 break;
  221.             case inGoAway:
  222.                 break;
  223.             case inGrow:
  224.                 if (whichWindow == FrontWindow()) {
  225.                     GetPort(&gp);
  226.                     SetPort(whichWindow);
  227.                     l = GrowWindow(whichWindow, &myEvent.where,
  228.                                 &sizeRect);
  229.                     h = l >> 16;
  230.                     w = l & 0x0000ffffL;
  231.                     SizeWindow(whichWindow, w, h, 0x100);
  232.                     SetPort(gp);
  233.                     }
  234.                 break;
  235.             case inContent:
  236.                 if (whichWindow != FrontWindow()) {
  237.                     SelectWindow(whichWindow);
  238.                     break;
  239.                     }
  240.                 break;
  241.  
  242.             case inZoomIn:
  243.             case inZoomOut:
  244.                 if (TrackBox(whichWindow, &myEvent.where, code)) {
  245.                     if (((WindowPeek)whichWindow)->dataHandle == 0) break;
  246.                     GetPort(&gp);
  247.                     SetPort(whichWindow);
  248.                     EraseRect(&(whichWindow->port.portRect));
  249.                     ZoomWindow(whichWindow, code, 0);
  250.                     SetPort(gp);
  251.                     }
  252.                 break;
  253.  
  254.             default:
  255.                 break;
  256.             }
  257.             break;
  258.  
  259.         case mouseUp:
  260.             break;
  261.  
  262.         case keyDown:
  263.         case autoKey:
  264.             break;
  265.  
  266.         case activateEvt:
  267.             break;
  268.  
  269.         case updateEvt:
  270.             updevent(myEvent.message);
  271.             break;
  272.  
  273.         case app4Evt:
  274.             break;
  275.  
  276.         default:    break;
  277.         }
  278. }
  279.  
  280. updevent(msgptr)
  281. GrafPtr msgptr;
  282. {
  283. GrafPtr gp;
  284.  
  285. GetPort(&gp);
  286. SetPort(msgptr);
  287. BeginUpdate(msgptr);
  288. EndUpdate(msgptr);
  289. SetPort(gp);
  290. }
  291.  
  292. menu_upd()
  293. {
  294. short i;
  295.  
  296. if (da_menu) {
  297.     for (i = 1; i < fileMSize; i++)
  298.         DisableItem(myMenus[1], i);
  299.     CheckItem(myMenus[1], fileMSize, 0);
  300.     }
  301. else {
  302.     if (defok) {
  303.         for (i = 1; i < fileMSize; i++)
  304.             EnableItem(myMenus[1], i);
  305.         }
  306.     else {
  307.         EnableItem(myMenus[1], 1);
  308.         for (i = 2; i < fileMSize; i++)
  309.             DisableItem(myMenus[1], i);
  310.         }
  311.     CheckItem(myMenus[1], fileMSize, done << 8);
  312.     }
  313. }
  314.  
  315. docommand(mResult)
  316. long mResult;
  317. {
  318. register short theItem, theMenu;
  319. char name[40];
  320. WindowRecord * fw;
  321. short i;
  322. static char nullstr[1] = {0};
  323. OSErr rc, readmap();
  324.  
  325. theMenu = mResult >> 16;
  326. theItem = mResult & 0xff;
  327. switch(theMenu) {
  328.     case appleMenu:
  329.         if (theItem == 2) break;
  330.         if (theItem == 1) {
  331.             aboutdlg();
  332.             break;
  333.             }
  334.         GetItem(myMenus[0], theItem, name);
  335.         OpenDeskAcc(name);
  336.         break;
  337.     case fileMenu:
  338.         switch (theItem) {
  339.             case 1:
  340.                     rc = readmap();
  341.                     defok = (rc == 0);
  342.                     break;
  343.             case 2:
  344.                     showinfo();
  345.                     break;
  346.             case 3:
  347.                     writetext();
  348.                     break;
  349.             case 4:
  350.                     writersc(0);
  351.                     break;
  352.             case 5:
  353.                     writersc(1);
  354.                     break;
  355.             case 6:
  356.                     if (!da_menu) {
  357.                         done ^= 1;
  358.                         break;
  359.                         }
  360.                     else {
  361.                         fw = (WindowRecord *)FrontWindow();
  362.                         i = fw->windowKind;
  363.                         if (i<0) CloseDeskAcc(i);
  364.                         }
  365.             default: break;
  366.             }
  367.         break;
  368.     case editMenu:
  369.         SystemEdit(theItem-1);
  370.         break;
  371.     default:
  372.         break;
  373.     }
  374.     HiliteMenu(0);
  375.     appl_menu();
  376. }
  377.  
  378. appl_menu()            /* enable correct application menus */
  379. {
  380. static char last_da = 2;    /* init to invalid value */
  381.  
  382. /* skip drawing menu if no changes from last time */
  383. if (last_da == da_menu) return;
  384. last_da = da_menu;        /* save values for next time */
  385.  
  386. if (da_menu) {
  387.     EnableItem(myMenus[2], 0);
  388.     }
  389. else {
  390.     DisableItem(myMenus[2], 0);
  391.     }
  392. DrawMenuBar();
  393. }
  394.  
  395. showerr(s)
  396. unsigned char * s;
  397. {
  398. static char nullstr[1] = {0};
  399.  
  400. ParamText(s, nullstr, nullstr, nullstr);
  401. StopAlert(256, 0L);
  402. ParamText(nullstr, nullstr, nullstr, nullstr);
  403. }
  404.  
  405. showerrln(s, l)
  406. unsigned char * s, * l;
  407. {
  408. static char nullstr[1] = {0};
  409.  
  410. ParamText(s, l, nullstr, nullstr);
  411. StopAlert(260, 0L);
  412. ParamText(nullstr, nullstr, nullstr, nullstr);
  413. }
  414.  
  415. ctralrt(a)
  416. short a;        /* alert number */
  417. {
  418. Handle reshnd;
  419. struct Rect * rptr;
  420. short scrhsize, scrvsize;
  421. short ahsize, avsize;
  422.  
  423. CouldAlert(a);        /* read alert into memory and make unpurgeable */
  424. reshnd = GetResource('ALRT', a);
  425. if (reshnd == 0) return;
  426. rptr = (struct Rect *)*reshnd;
  427. scrhsize = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
  428. scrvsize = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
  429. ahsize = rptr->right - rptr->left;
  430. avsize = rptr->bottom - rptr->top;
  431. rptr->top = (scrvsize-avsize)/3;
  432. rptr->left = (scrhsize-ahsize)/2;
  433. rptr->bottom = rptr->top + avsize;
  434. rptr->right = rptr->left + ahsize;
  435. }
  436.  
  437. OSErr fsrdopen(fname, vref, fref)    /* open file read-only */
  438. char * fname;
  439. short vref;
  440. short * fref;
  441. {
  442. IOParam pbi;
  443. OSErr rc;
  444.  
  445. /* initialize parameter block */
  446. memset(&pbi, 0, sizeof(IOParam));
  447.  
  448. pbi.ioNamePtr = (StringPtr)fname;
  449. pbi.ioVRefNum = vref;
  450. pbi.ioPermssn = fsRdPerm;
  451. rc = PBOpen(&pbi, 0);
  452. *fref = pbi.ioRefNum;
  453. return(rc);
  454. }
  455.  
  456. aboutdlg()
  457. {
  458. DialogPtr dlgptr;
  459. short itemHit, len;
  460. unsigned char **version;
  461. static char nullstr[1] = {0};
  462. unsigned char verstring[256];
  463.  
  464. dlgptr = GetNewDialog(257, (Ptr)0L, (WindowPtr)-1L);
  465. ctrwindow(dlgptr);
  466. version = GetResource('GFTK', 0);
  467. if (version == 0L) {
  468.     DisposDialog(dlgptr);
  469.     return;
  470.     }
  471. len = (*version)[0];
  472. if (len > 0) {
  473.     memcpy(verstring, (*version)+1, len);
  474.     }
  475. verstring[len] = 0;
  476. ParamText(verstring, nullstr, nullstr, nullstr);
  477. ShowWindow(dlgptr);
  478.  
  479. /* frame the default selection */
  480. framedflt(dlgptr);
  481.  
  482. ModalDialog(0L, &itemHit);
  483. DisposDialog(dlgptr);
  484. ParamText(nullstr, nullstr, nullstr, nullstr);
  485. }
  486.  
  487. ctrwindow(wp)
  488. GrafPtr wp;
  489. {
  490. short scrhsize, scrvsize;
  491. short whsize, wvsize;
  492.  
  493. scrhsize = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
  494. scrvsize = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
  495. whsize = wp->portRect.right-wp->portRect.left;
  496. wvsize = wp->portRect.bottom - wp->portRect.top;
  497. MoveWindow(wp, (scrhsize-whsize)/2, (scrvsize-wvsize)/3, 0);
  498. }
  499.  
  500. framedflt(dlgptr)
  501. DialogPtr dlgptr;
  502. {
  503. short gtype;
  504. Handle gitem;
  505. Rect gbox;
  506. GrafPtr gp;
  507.  
  508. GetDItem(dlgptr, 1, >ype, &gitem, &gbox);
  509. GetPort(&gp);
  510. SetPort(dlgptr);
  511. PenSize(3,3);
  512. InsetRect(&gbox, -4, -4);
  513. FrameRoundRect(&gbox, 16, 16);
  514. SetPort(gp);
  515. }
  516.  
  517. OSErr readmap()        /* read definition file to define name and arrays */
  518. {
  519. Point where;
  520. char * prompt;
  521. unsigned short (*fileFilter)();
  522. short numTypes;
  523. SFReply reply;
  524. SFTypeList typeList;
  525. ProcPtr dlgHook;
  526. pascal unsigned short onlydata();
  527. unsigned char errtext[256];
  528. short fref;
  529. OSErr rc;
  530. short linenum, linerc;
  531. unsigned char textchar;
  532. unsigned char textline[256];
  533. short textlen;
  534. unsigned char commentflag;
  535. long fcount;
  536. short newline();
  537.  
  538. /* open definition file */
  539.  
  540. where = sfgpoint;
  541. prompt = 0;
  542. dlgHook = 0;
  543. fileFilter = onlydata;
  544. numTypes = 2;
  545. typeList[0] = 'TEXT';
  546. typeList[1] = 'ttro';
  547. SFGetFile(&where, prompt, fileFilter, numTypes,
  548.     typeList, dlgHook, &reply);
  549. if (reply.good == 0) return(defok == 0);    /* user selected "cancel" */
  550. defreply = reply;                /* save good data */
  551. rc = fsrdopen(&defreply.fName, defreply.vRefNum, &fref);
  552. if (rc != 0) {
  553.     p2cstr(&defreply.fName);
  554.     sprintf(errtext, "Error %d opening %s", rc, &defreply.fName);
  555.     c2pstr(&defreply.fName);
  556.     showerr(errtext);
  557.     return(rc);
  558.     }
  559.     
  560. /* read file and process each line */
  561. strcpy(mapname, "unnamed");        /* set default name */
  562. mapnum = DEFAULTNUM;            /* set default number */
  563.                                 /* initialize mapping arrays */
  564. memset(keybuffn, 0, 128); 
  565. memset(keybuffs, 0, 128); 
  566. memset(keybuffc, 0, 128); 
  567. memset(keybuffcs, 0, 128);
  568. memset(keybuffo, 0, 128);
  569. memset(ascbuffn, 0, 256);
  570. memset(ascbuffs, 0, 256);
  571. memset(ascbuffc, 0, 256);
  572. memset(ascbuffcs, 0, 256);
  573. memset(ascbuffo, 0, 256);
  574. memset(hexbuff, 0, sizeof(hexmap)*256);
  575. hexcount = 0;
  576. linenum = 0;
  577. textlen = 0;
  578. commentflag = 0;
  579. fcount = 1;
  580. linerc = 0;
  581. rc = FSRead(fref, &fcount, &textchar);
  582. while ((rc == 0) && (linerc == 0)) {    /* process new character */
  583.     switch (textchar) {
  584.         case 0x0d:                /* end of line */
  585.                 linenum++;
  586.                 textline[textlen] = 0;
  587.                 linerc = newline(textline, linenum);
  588.                 textlen = 0;
  589.                 commentflag = 0;
  590.                 break;
  591.         case '#':                /* start of comment */
  592.                 commentflag = 1;
  593.                 break;
  594.         case 0x00:                /* null */
  595.         case 0x09:                /* tab */
  596.         case 0x0a:                /* linefeed */
  597.         case 0x0b:                /* vertical tab */
  598.         case 0x0c:                /* formfeed */
  599.         case 0x20:                /* blank */
  600.                 break;
  601.         default:
  602.                 if (commentflag) break;
  603.                 if (textlen == 255) {
  604.                     sprintf(errtext, 
  605.                         "Line %d truncated to first 255 characters:",
  606.                         linenum+1);
  607.                     textline[textlen] = 0;
  608.                     showerrln(errtext, textline);
  609.                     commentflag = 1;
  610.                     break;
  611.                     }
  612.                 textline[textlen++] = textchar;
  613.                 break;
  614.         }
  615.     fcount = 1;
  616.     rc = FSRead(fref, &fcount, &textchar);
  617.     }
  618. if ((rc != eofErr) && (rc != 0)) {
  619.     sprintf(errtext, "Error %d reading definition file.", rc);
  620.     showerr(errtext);
  621.     FSClose(fref);
  622.     return(rc);
  623.     }
  624. else if ((textlen > 0) && (linerc == 0)) {
  625.     linenum++;
  626.     textline[textlen] = 0;
  627.     linerc = newline(textline, linenum);
  628.     }
  629. FSClose(fref);
  630. return(linerc);
  631. }
  632.  
  633. short newline(text, lineno)
  634. unsigned char * text;
  635. short lineno;
  636. {
  637. unsigned char errtext[256];
  638. short textlen, idlen, modlen;
  639. unsigned char textbuff[64];
  640. register int i, j;
  641. unsigned char c, usflag, state;
  642. unsigned char valtype, valnum, idnum, hexnum;
  643. unsigned char id[64];
  644. unsigned char mod[64];
  645. unsigned char * tabptr1, * tabptr2;
  646. static unsigned char * modnames[] = {
  647.     "NORMAL", "SHIFT", "COMMAND", "COMMAND-SHIFT", "OPTION"};
  648. static unsigned char * namelist[] = {
  649.     /* 000 */    "SPACE",
  650.     /* 001 */    "CENT",
  651.     /* 002 */    "PERIOD",
  652.     /* 003 */    "LESS",
  653.     /* 004 */    "LPAREN",
  654.     /* 005 */    "PLUS",
  655.     /* 006 */    "OR",
  656.     /* 007 */    "AMPERSAND",
  657.     /* 008 */    "EXCLAIM",
  658.     /* 009 */    "DOLLAR",
  659.     /* 010 */    "ASTERISK",
  660.     /* 011 */    "RPAREN",
  661.     /* 012 */    "SEMI",
  662.     /* 013 */    "NOT",
  663.     /* 014 */    "MINUS",
  664.     /* 015 */    "SLASH",
  665.     /* 016 */    "VERTICAL",
  666.     /* 017 */    "COMMA",
  667.     /* 018 */    "PERCENT",
  668.     /* 019 */    "UNDERSCORE",
  669.     /* 020 */    "GREATER",
  670.     /* 021 */    "QUESTION",
  671.     /* 022 */    "ACCENT",
  672.     /* 023 */    "COLON",
  673.     /* 024 */    "POUND",
  674.     /* 025 */    "AT",
  675.     /* 026 */    "APOSTROPHE",
  676.     /* 027 */    "EQUAL",
  677.     /* 028 */    "DBLQUOTE",
  678.     /* 029 */    "LCA",
  679.     /* 030 */    "LCB",
  680.     /* 031 */    "LCC",
  681.     /* 032 */    "LCD",
  682.     /* 033 */    "LCE",
  683.     /* 034 */    "LCF",
  684.     /* 035 */    "LCG",
  685.     /* 036 */    "LCH",
  686.     /* 037 */    "LCI",
  687.     /* 038 */    "LCJ",
  688.     /* 039 */    "LCK",
  689.     /* 040 */    "LCL",
  690.     /* 041 */    "LCM",
  691.     /* 042 */    "LCN",
  692.     /* 043 */    "LCO",
  693.     /* 044 */    "LCP",
  694.     /* 045 */    "LCQ",
  695.     /* 046 */    "LCR",
  696.     /* 047 */    "TILDE",
  697.     /* 048 */    "LCS",
  698.     /* 049 */    "LCT",
  699.     /* 050 */    "LCU",
  700.     /* 051 */    "LCV",
  701.     /* 052 */    "LCW",
  702.     /* 053 */    "LCX",
  703.     /* 054 */    "LCY",
  704.     /* 055 */    "LCZ",
  705.     /* 056 */    "LBRACK",
  706.     /* 057 */    "RBRACK",
  707.     /* 058 */    "LBRACE",
  708.     /* 059 */    "A",
  709.     /* 060 */    "B",
  710.     /* 061 */    "C",
  711.     /* 062 */    "D",
  712.     /* 063 */    "E",
  713.     /* 064 */    "F",
  714.     /* 065 */    "G",
  715.     /* 066 */    "H",
  716.     /* 067 */    "I",
  717.     /* 068 */    "RBRACE",
  718.     /* 069 */    "J",
  719.     /* 070 */    "K",
  720.     /* 071 */    "L",
  721.     /* 072 */    "M",
  722.     /* 073 */    "N",
  723.     /* 074 */    "O",
  724.     /* 075 */    "P",
  725.     /* 076 */    "Q",
  726.     /* 077 */    "R",
  727.     /* 078 */    "BACKSLASH",
  728.     /* 079 */    "S",
  729.     /* 080 */    "T",
  730.     /* 081 */    "U",
  731.     /* 082 */    "V",
  732.     /* 083 */    "W",
  733.     /* 084 */    "X",
  734.     /* 085 */    "Y",
  735.     /* 086 */    "Z",
  736.     /* 087 */    "0",
  737.     /* 088 */    "1",
  738.     /* 089 */    "2",
  739.     /* 090 */    "3",
  740.     /* 091 */    "4",
  741.     /* 092 */    "5",
  742.     /* 093 */    "6",
  743.     /* 094 */    "7",
  744.     /* 095 */    "8",
  745.     /* 096 */    "9",
  746.     /* 097 */    "A_",
  747.     /* 098 */    "B_",
  748.     /* 099 */    "C_",
  749.     /* 100 */    "D_",
  750.     /* 101 */    "E_",
  751.     /* 102 */    "F_",
  752.     /* 103 */    "G_",
  753.     /* 104 */    "H_",
  754.     /* 105 */    "I_",
  755.     /* 106 */    "J_",
  756.     /* 107 */    "K_",
  757.     /* 108 */    "L_",
  758.     /* 109 */    "M_",
  759.     /* 110 */    "N_",
  760.     /* 111 */    "O_",
  761.     /* 112 */    "P_",
  762.     /* 113 */    "Q_",
  763.     /* 114 */    "R_",
  764.     /* 115 */    "S_",
  765.     /* 116 */    "T_",
  766.     /* 117 */    "U_",
  767.     /* 118 */    "V_",
  768.     /* 119 */    "W_",
  769.     /* 120 */    "X_",
  770.     /* 121 */    "Y_",
  771.     /* 122 */    "Z_",
  772.     /* 123 */    "I-BEAM",
  773.     /* 124 */    "DEL-TILDE",
  774.     /* 125 */    "GRADE-DOWN",
  775.     /* 126 */    "GRADE-UP",
  776.     /* 127 */    "VERT-ROTATE",
  777.     /* 128 */    "TRANSPOSE",
  778.     /* 129 */    "HOR-ROTATE",
  779.     /* 130 */    "LOGARITHM",
  780.     /* 131 */    "NOR",
  781.     /* 132 */    "NAND",
  782.     /* 133 */    "APL-EXCLAIM",
  783.     /* 134 */    "DOMINO",
  784.     /* 135 */    "QUOTE-QUAD",
  785.     /* 136 */    "DELTA_",
  786.     /* 137 */    "FORMAT",
  787.     /* 138 */    "EXECUTE",
  788.     /* 139 */    "LAMP",
  789.     /* 140 */    "EXPAND",
  790.     /* 141 */    "COMPRESS",
  791.     /* 142 */    "ENTER",
  792.     /* 143 */    "PF1",
  793.     /* 144 */    "PF2",
  794.     /* 145 */    "PF3",
  795.     /* 146 */    "PF4",
  796.     /* 147 */    "PF5",
  797.     /* 148 */    "PF6",
  798.     /* 149 */    "PF7",
  799.     /* 150 */    "PF8",
  800.     /* 151 */    "PF9",
  801.     /* 152 */    "PF10",
  802.     /* 153 */    "PF11",
  803.     /* 154 */    "PF12",
  804.     /* 155 */    "PF13",
  805.     /* 156 */    "PF14",
  806.     /* 157 */    "PF15",
  807.     /* 158 */    "PF16",
  808.     /* 159 */    "PF17",
  809.     /* 160 */    "PF18",
  810.     /* 161 */    "PF19",
  811.     /* 162 */    "PF20",
  812.     /* 163 */    "PF21",
  813.     /* 164 */    "PF22",
  814.     /* 165 */    "PF23",
  815.     /* 166 */    "PF24",
  816.     /* 167 */    "PA1",
  817.     /* 168 */    "PA2",
  818.     /* 169 */    "PA3",
  819.     /* 170 */    "CLEAR",
  820.     /* 171 */    "TREQ",
  821.     /* 172 */    "CURSEL",
  822.     /* 173 */    "UP",
  823.     /* 174 */    "DOWN",
  824.     /* 175 */    "LEFT",
  825.     /* 176 */    "RIGHT",
  826.     /* 177 */    "TAB",
  827.     /* 178 */    "BACKTAB",
  828.     /* 179 */    "NEWLINE",
  829.     /* 180 */    "HOME",
  830.     /* 181 */    "ERASE-EOF",
  831.     /* 182 */    "ERASE-INPUT",
  832.     /* 183 */    "INSERT-MODE",
  833.     /* 184 */    "DELETE-CHAR",
  834.     /* 185 */    "RESET",
  835.     /* 186 */    "DUP",
  836.     /* 187 */    "FIELD-MARK",
  837.     /* 188 */    "APL-MODE",
  838.     /* 189 */    "INSERT-CHAR",
  839.     /* 190 */    "RUB-OUT",
  840.     /* 191 */    "UP*2",
  841.     /* 192 */    "DOWN*2",
  842.     /* 193 */    "LEFT*2",
  843.     /* 194 */    "RIGHT*2",
  844.     /* 195 */    "CURSOR-POS",
  845.     /* 196 */    "PROG-RESET",
  846.     };
  847.     
  848. static hexinfo hexlist[] = {
  849.     {"LEFT_TACK", 0x2A},
  850.     {"POINTER", 0x38},
  851.     {"PARAGRAPH", 0x39},
  852.     {"SINGLE_DAGGER", 0x3A},
  853.     {"DOUBLE_DAGGER", 0x3B},
  854.     {"POLISH_L", 0x41},
  855.     {"SLASH_O", 0x42},
  856.     {"D_CROSSED", 0x43},
  857.     {"THORN", 0x44},
  858.     {"AE", 0x45},
  859.     {"OE", 0x46},
  860.     {"HOOK_O", 0x47},
  861.     {"HOOK_U", 0x48},
  862.     {"MIAGKIY_ZNAK", 0x49},
  863.     {"LCPOLISH_L", 0x51},
  864.     {"LCSLASH_O", 0x52},
  865.     {"LCD_CROSSED", 0x53},
  866.     {"LCTHORN", 0x54},
  867.     {"LCAE", 0x55},
  868.     {"LCOE", 0x56},
  869.     {"LCHOOK_O", 0x57},
  870.     {"LCHOOK_U", 0x58},
  871.     {"TVERDYI_ZNAK", 0x59},
  872.     {"AYN", 0x62},
  873.     {"ALF", 0x63},
  874.     {"MIDDLE_DOT", 0x64},
  875.     {"TURKISH_I", 0x65},
  876.     {"FLAT", 0x66},
  877.     {"PATENT", 0x67},
  878.     {"ETH", 0x68},
  879.     {"PLUS_OR_MINUS", 0x69},
  880.     {"SUB0", 0x70},
  881.     {"SUB1", 0x71},
  882.     {"SUB2", 0x72},
  883.     {"SUB3", 0x73},
  884.     {"SUB4", 0x74},
  885.     {"SUB5", 0x75},
  886.     {"SUB6", 0x76},
  887.     {"SUB7", 0x77},
  888.     {"SUB8", 0x78},
  889.     {"SCRIPT_L", 0x80},
  890.     {"ANGSTROM", 0x8A},
  891.     {"SUPERIOR_DOT", 0x8B},
  892.     {"UMLAUT", 0x8C},
  893.     {"CANDRABINDU", 0x8D},
  894.     {"LEFT_LIGATURE", 0x8E},
  895.     {"LEFT_D_TILDE", 0x8F},
  896.     {"SUB9", 0x90},
  897.     {"GRAVE", 0x9A},
  898.     {"ACUTE", 0x9B},
  899.     {"ALA_CIRCUMFLEX", 0x9C},
  900.     {"HACEK", 0x9D},
  901.     {"RIGHT_LIGATURE", 0x9E},
  902.     {"RIGHT_D_TILDE", 0x9F},
  903.     {"ALA_DAGGER", 0xA0},
  904.     {"SUB_PLUS", 0xAA},
  905.     {"SUB_LPAREN", 0xAB},
  906.     {"PINCUSHION", 0xAC},
  907.     {"SUB_MINUS", 0xAE},
  908.     {"SUB_RPAREN", 0xAF},
  909.     {"SUP0", 0xB0},
  910.     {"SUP1", 0xB1},
  911.     {"SUP2", 0xB2},
  912.     {"SUP3", 0xB3},
  913.     {"SUP4", 0xB4},
  914.     {"SUP5", 0xB5},
  915.     {"SUP6", 0xB6},
  916.     {"SUP7", 0xB7},
  917.     {"SUP8", 0xB8},
  918.     {"SUP9", 0xB9},
  919.     {"SUP_PLUS", 0xBA},
  920.     {"SUP_LPAREN", 0xBB},
  921.     {"ASPER", 0xBC},
  922.     {"SUP_MINUS", 0xBE},
  923.     {"SUP_RPAREN", 0xBF},
  924.     {"CIRCLE_BELOW", 0xCA},
  925.     {"DOT_BELOW", 0xCB},
  926.     {"DOUBLE_DOT_BELOW", 0xCC},
  927.     {"BREVE", 0xCD},
  928.     {"ALA_TILDE", 0xCE},
  929.     {"PSEUDO_QUEST", 0xCF},
  930.     {"CEDILLA", 0xDA},
  931.     {"HIGH_COMMA_CTR", 0xDB},
  932.     {"RIGHT_HOOK", 0xDC},
  933.     {"UPADHMANIYA", 0xDD},
  934.     {"MACRON", 0xDE},
  935.     {"DOUBLE_ACUTE", 0xDF},
  936.     {"BRITISH_POUND", 0xE1},
  937.     {"RIGHT_CEDILLA", 0xEA},
  938.     {"HIGH_COMMA", 0xEB},
  939.     {"LEFT_HOOK", 0xEC},
  940.     {"ALA_UNDERSCORE", 0xED},
  941.     {"DOUBLE_UNDERSCORE", 0xEE},
  942.     {"ALA_ALPHA", 0xFA},
  943.     {"ALA_BETA", 0xFB},
  944.     {"ALA_GAMMA", 0xFC},
  945.     {"YEN", 0xFD},
  946.     {"PESO", 0xFE}};
  947.  
  948. textlen = strlen(text);
  949.  
  950. /* skip null lines */
  951. if (textlen == 0) return (0);
  952.  
  953. /* check for name definition line */
  954. if (textlen > 5) {
  955.     for (i=0; i < 5; i++) 
  956.         textbuff[i] = toupper(text[i]);
  957.     if (strncmp(textbuff, "NAME:", 5) == 0) {
  958.         i = 0;
  959.         j = i + 5;
  960.         usflag = 0;
  961.         while (i < 63) {
  962.             c = text[j++];
  963.             if (usflag) {
  964.                 if (c == '_') {
  965.                     mapname[i++] = '_';
  966.                     }
  967.                 else {
  968.                     mapname[i++] = ' ';
  969.                     if (i < 63) {
  970.                         mapname[i++] = c;
  971.                         if (c == 0) break;
  972.                         }
  973.                     }
  974.                 usflag = 0;
  975.                 }
  976.             else if (c == '_') {
  977.                 usflag = 1;
  978.                 }
  979.             else {
  980.                 mapname[i++] = c;
  981.                 if (c == 0) break;
  982.                 }
  983.             }
  984.         mapname[63] = 0;
  985.         return(0);
  986.         }
  987.     }
  988.  
  989. /* check for number definition line */
  990. if (textlen > 7) {
  991.     for (i=0; i < 7; i++) 
  992.         textbuff[i] = toupper(text[i]);
  993.     if (strncmp(textbuff, "NUMBER:", 7) == 0) {
  994.         c = 0;
  995.         for (i=7; i < textlen; i++) {
  996.             c = text[i];
  997.             if ((c < '0') || (c > '9')) break;
  998.             }
  999.         if ((c >= '0') && (c <= '9')) {
  1000.             mapnum = atoi(text+7);
  1001.             return(0);
  1002.             }
  1003.         }
  1004.     }
  1005.  
  1006. /* process mapping definition line */
  1007.  
  1008. state = 0;
  1009. idlen = modlen = 0;
  1010. for (i=0; i < textlen; i++) {
  1011.     c = text[i];
  1012.     switch(state) {
  1013.         case 0:                    /* first character */
  1014.                 if (c == '=') {
  1015.                     state = 99;
  1016.                     }
  1017.                 else {
  1018.                     id[idlen++] = toupper(c);
  1019.                     state = 1;
  1020.                     }
  1021.                 break;
  1022.         case 1:                    /* characters of id */
  1023.                 if (c == '=') {
  1024.                     id[idlen] = 0;
  1025.                     state = 2;
  1026.                     }
  1027.                 else {
  1028.                     if (idlen < 63) id[idlen++] = toupper(c);
  1029.                     else state = 99;
  1030.                     }
  1031.                 break;
  1032.         case 2:                    /* characters in modifier */
  1033.                 if (c == '\'') {
  1034.                     mod[modlen] = 0;
  1035.                     state = 3;
  1036.                     }
  1037.                 else if (c == '"') {
  1038.                     mod[modlen] = 0;
  1039.                     state = 5;
  1040.                     }
  1041.                 else {
  1042.                     if (modlen < 63) mod[modlen++] = toupper(c);
  1043.                     else state = 99;
  1044.                     }
  1045.                 break;
  1046.         case 3:                    /* literal character value */
  1047.                 valtype = 0;
  1048.                 valnum = c;
  1049.                 state = 4;
  1050.                 break;
  1051.         case 4:                    /* end of character literal */
  1052.                 if (c == '\'') state = 9;
  1053.                 else state = 99;
  1054.                 break;
  1055.         case 5:                    /* start of hex string */
  1056.                 c = toupper(c);
  1057.                 if ((c >= 'A') && (c <= 'F')) {
  1058.                     valtype = 0;
  1059.                     valnum = (c - 'A' + 10) << 4;
  1060.                     state = 7;
  1061.                     }
  1062.                 else if ((c >= '0') && (c <= '9')) {
  1063.                     valtype = 0;
  1064.                     valnum = (c - '0') << 4;
  1065.                     state = 7;
  1066.                     }
  1067.                 else if (c == 'K') {
  1068.                     valtype = 6;
  1069.                     state = 6;
  1070.                     }
  1071.                 else state = 99;
  1072.                 break;
  1073.         case 6:                    /* after "K" in string */
  1074.                 c = toupper(c);
  1075.                 if ((c >= 'A') && (c <= 'F')) {
  1076.                     valnum = (c - 'A' + 10) << 4;
  1077.                     state = 7;
  1078.                     }
  1079.                 else if ((c >= '0') && (c <= '9')) {
  1080.                     valnum = (c - '0') << 4;
  1081.                     state = 7;
  1082.                     }
  1083.                 else state = 99;
  1084.                 break;
  1085.         case 7:                    /* after first hex digit */
  1086.                 c = toupper(c);
  1087.                 if ((c >= 'A') && (c <= 'F')) {
  1088.                     valnum += c - 'A' + 10;
  1089.                     state = 8;
  1090.                     }
  1091.                 else if ((c >= '0') && (c <= '9')) {
  1092.                     valnum += c - '0';
  1093.                     state = 8;
  1094.                     }
  1095.                 else state = 99;
  1096.                 break;
  1097.         case 8:                    /* end of hex string */
  1098.                 if (c == '"') state = 9;
  1099.                 else state = 99;
  1100.                 break;
  1101.         case 9:                    /* after complete definition */
  1102.         default:
  1103.                 state = 99;
  1104.                 break;
  1105.         }
  1106.     if (state == 99) break;        /* syntax error */
  1107.     }
  1108.  
  1109. if (state != 9) {            /* error if not in finishing state */
  1110.     sprintf(errtext, "Syntax error in definition file at line %d:",
  1111.         lineno);
  1112.     showerrln(errtext, text);
  1113.     return(4);
  1114.     }
  1115.     
  1116. /* apply modifier, if any to valtype */
  1117. if (modlen > 0) {
  1118.     j = -1;
  1119.     for (i=0; i < sizeof(modnames) >> 2; i++) {
  1120.         if (strcmp(mod, modnames[i]) == 0) {
  1121.             j = i;
  1122.             break;
  1123.             }
  1124.         }
  1125.     if (j < 0) {
  1126.         sprintf(errtext, "Invalid modifier value '%s' at line %d:",
  1127.             mod, lineno);
  1128.         showerrln(errtext, text);
  1129.         return(8);
  1130.         }
  1131.     else valtype += j+1;
  1132.     }
  1133.     
  1134. /* check that keycode value is legal */
  1135. if ((valtype >= 6) && (valnum > 127)) {
  1136.     sprintf(errtext, "Key code '%x' exceeds 7f at line %d:",
  1137.         valnum, lineno);
  1138.     showerrln(errtext, text);
  1139.     return(12);
  1140.     }
  1141.     
  1142. /* convert function id table index */
  1143. j = -1;
  1144. for (i=0; i < sizeof(namelist) >> 2; i++) {
  1145.     if (strcmp(id, namelist[i]) == 0) {
  1146.         j = i;
  1147.         break;
  1148.         }
  1149.     }
  1150.  
  1151. if (j >= 0) {
  1152.     idnum = j;
  1153.     hexnum = 0;
  1154.     }
  1155. else {            /* search hex name table */
  1156.     for (i=0; i < sizeof(hexlist)/sizeof(hexinfo); i++) {
  1157.         if (strcmp(id, (hexlist[i]).hexname) == 0) {
  1158.             idnum = j = 254;
  1159.             hexnum = (hexlist[i]).hexvalue;
  1160.             break;
  1161.             }
  1162.         }
  1163.     }
  1164. if (j < 0) {
  1165.     sprintf(errtext, "Invalid key or function name '%s' at line %d:",
  1166.         id, lineno);
  1167.     showerrln(errtext, text);
  1168.     return(16);
  1169.     }
  1170.  
  1171. tabptr2 = 0;
  1172. switch(valtype) {
  1173.     case 0:        tabptr1 = ascbuffn;
  1174.                 tabptr2 = ascbuffs;
  1175.                 break;
  1176.     case 1:        tabptr1 = ascbuffn;
  1177.                 break;
  1178.     case 2:        tabptr1 = ascbuffs;
  1179.                 break;
  1180.     case 3:        tabptr1 = ascbuffc;
  1181.                 break;
  1182.     case 4:        tabptr1 = ascbuffcs;
  1183.                 break;
  1184.     case 5:        tabptr1 = ascbuffo;
  1185.                 break;
  1186.     case 6:        tabptr1 = keybuffn;
  1187.                 break;
  1188.     case 7:        tabptr1 = keybuffn;
  1189.                 break;
  1190.     case 8:        tabptr1 = keybuffs;
  1191.                 break;
  1192.     case 9:        tabptr1 = keybuffc;
  1193.                 break;
  1194.     case 10:    tabptr1 = keybuffcs;
  1195.                 break;
  1196.     case 11:    tabptr1 = keybuffo;
  1197.                 break;
  1198.     default:
  1199.             return(20);        /* can't happen */
  1200.             break;
  1201.     }
  1202.  
  1203. tabptr1 += valnum;
  1204. if ((*tabptr1) == 0) {
  1205.     (*tabptr1) = idnum + 1;
  1206.     if (hexnum > 0) {
  1207.         if (hexcount == 256) {
  1208.             sprintf(errtext, "Number of hex mappings exceeds 256 at line %d:",
  1209.                 lineno);
  1210.             showerrln(errtext, text);
  1211.             return(16);
  1212.             }
  1213.         (hexbuff[hexcount]).offset = tabptr1 - keybuffn;
  1214.         (hexbuff[hexcount]).stdchar = hexnum;
  1215.         (hexbuff[hexcount++]).aplchar = 0;
  1216.         }
  1217.     }
  1218. else {
  1219.     sprintf(errtext, "Duplicate key definition at line %d:",
  1220.         lineno);
  1221.     showerrln(errtext, text);
  1222.     return(24);
  1223.     }
  1224.  
  1225. if (tabptr2 != 0) {
  1226.     tabptr2 += valnum;
  1227.     if ((*tabptr2) == 0) {
  1228.         (*tabptr2) = idnum + 1;
  1229.         if (hexnum > 0) {
  1230.             if (hexcount == 256) {
  1231.                 sprintf(errtext, "Number of hex mappings exceeds 256 at line %d:",
  1232.                     lineno);
  1233.                 showerrln(errtext, text);
  1234.                 return(16);
  1235.                 }
  1236.             (hexbuff[hexcount]).offset = tabptr2 - keybuffn;
  1237.             (hexbuff[hexcount]).stdchar = hexnum;
  1238.             (hexbuff[hexcount++]).aplchar = 0;
  1239.             }
  1240.         }
  1241.     else {
  1242.         sprintf(errtext, "Duplicate key definition at line %d:",
  1243.             lineno);
  1244.         showerrln(errtext, text);
  1245.         return(24);
  1246.         }
  1247.     }
  1248. return (0);
  1249. }
  1250.  
  1251. pascal unsigned short onlydata(_pb)
  1252. FileParam * _pb;
  1253. {
  1254. if (_pb->ioFlLgLen == 0L) return(0x100);
  1255.     else return(0);
  1256. }
  1257.  
  1258. writetext()            /* write resource to Rez format file */
  1259. {
  1260. Point where;
  1261. ProcPtr dlgHook;
  1262. SFReply reply;
  1263. OSErr rc, writearray(), writehex();
  1264. short fnum;
  1265. char outtext[256];
  1266. long outcount;
  1267.  
  1268. where = sfppoint;
  1269. dlgHook = 0;
  1270. strcpy(outtext, mapname);
  1271. strcat(outtext, ".r");
  1272. SFPutFile(&where, "Save in Rez format as:",
  1273.           outtext, dlgHook, &reply);
  1274. if (reply.good == 0) return;
  1275. p2cstr(&reply.fName);
  1276. rc = FSDelete(&reply.fName, reply.vRefNum);        /* delete existing file */
  1277. rc = Create(&reply.fName, reply.vRefNum, 'MPS ', 'TEXT');
  1278. if (rc != 0) {
  1279.     sprintf(outtext, "Error %d creating output file.", rc);
  1280.     showerr(outtext);
  1281.     return;
  1282.     }
  1283. rc = FSOpen(&reply.fName, reply.vRefNum, &fnum);
  1284. if (rc != 0) {
  1285.     sprintf(outtext, "Error %d opening output file.", rc);
  1286.     showerr(outtext);
  1287.     return;
  1288.     }
  1289.     
  1290. sprintf(outtext, "data \'GFKB\' (%d, \"%s\", preload) {\n", 
  1291.     mapnum, mapname);
  1292. outcount = strlen(outtext);
  1293. rc = FSWrite(fnum, &outcount, outtext);
  1294.  
  1295. if (rc == 0) 
  1296.     rc = writearray("keybuffn", keybuffn, 128, fnum);
  1297. if (rc == 0) 
  1298.     rc = writearray("keybuffs", keybuffs, 128, fnum);
  1299. if (rc == 0) 
  1300.     rc = writearray("keybuffc", keybuffc, 128, fnum);
  1301. if (rc == 0)
  1302.     rc = writearray("keybuffcs", keybuffcs, 128, fnum);
  1303. if (rc == 0) 
  1304.     rc = writearray("keybuffo", keybuffo, 128, fnum);
  1305. if (rc == 0) 
  1306.     rc = writearray("ascbuffn", ascbuffn, 256, fnum);
  1307. if (rc == 0) 
  1308.     rc = writearray("ascbuffs", ascbuffs, 256, fnum);
  1309. if (rc == 0) 
  1310.     rc = writearray("ascbuffc", ascbuffc, 256, fnum);
  1311. if (rc == 0)
  1312.     rc = writearray("ascbuffcs", ascbuffcs, 256, fnum);
  1313. if (rc == 0) 
  1314.     rc = writearray("ascbuffo", ascbuffo, 256, fnum);
  1315. if ((hexcount > 0) && (rc == 0))
  1316.     rc = writehex(fnum);
  1317.  
  1318. if (rc == 0) {
  1319.     sprintf(outtext, "};\n");
  1320.     outcount = strlen(outtext);
  1321.     rc = FSWrite(fnum, &outcount, outtext);
  1322.     }
  1323.     
  1324. if (rc != 0) {
  1325.     sprintf(outtext, "Error %d writing output file.", rc);
  1326.     showerr(outtext);
  1327.     }
  1328.  
  1329. FSClose(fnum);
  1330. }
  1331.     
  1332. OSErr writearray(name, a, len, fnum)
  1333. unsigned char *name, *a;
  1334. short len, fnum;
  1335. {
  1336. OSErr rc;
  1337. long outcount;
  1338. register int i, j;
  1339. char outtext[256];
  1340.  
  1341. sprintf(outtext, "\t\t\t\t\t\t\t\t\t\t\t/* %s */\n", name);
  1342. outcount = strlen(outtext);
  1343. rc = FSWrite(fnum, &outcount, outtext);
  1344. if (rc != 0) return(rc);
  1345.  
  1346. for (i = 0; i < len; i +=16) {
  1347.     sprintf(outtext, 
  1348. "$\"%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\"\n",
  1349.     a[i], a[i+1], a[i+2], a[i+3], a[i+4], a[i+5], a[i+6], a[i+7],
  1350.     a[i+8], a[i+9], a[i+10], a[i+11], a[i+12], a[i+13], a[i+14], a[i+15]);
  1351.     for (j=0; j < strlen(outtext); j++)
  1352.         outtext[j] = toupper(outtext[j]);
  1353.     outcount = strlen(outtext);
  1354.     rc = FSWrite(fnum, &outcount, outtext);
  1355.     if (rc != 0) return(rc);
  1356.     }
  1357. return(0);
  1358. }
  1359.  
  1360. OSErr writehex(fnum)
  1361. short fnum;
  1362. {
  1363. OSErr rc;
  1364. long outcount;
  1365. register int i, j;
  1366. char outtext[256];
  1367. unsigned char *a;
  1368. int wholelines, extrawords;
  1369. char wordbuff[12];
  1370.  
  1371. sprintf(outtext, "\t\t\t\t\t\t\t\t\t\t\t/* %s */\n", "hexbuff");
  1372. outcount = strlen(outtext);
  1373. rc = FSWrite(fnum, &outcount, outtext);
  1374. if (rc != 0) return(rc);
  1375.  
  1376. wholelines = hexcount / 4;
  1377. extrawords = hexcount % 4;
  1378. a = hexbuff;
  1379. i = 0;
  1380. if (wholelines > 0) {
  1381.     for (i = 0; i < wholelines*16; i +=16) {
  1382.         sprintf(outtext, 
  1383.     "$\"%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\"\n",
  1384.         a[i], a[i+1], a[i+2], a[i+3], a[i+4], a[i+5], a[i+6], a[i+7],
  1385.         a[i+8], a[i+9], a[i+10], a[i+11], a[i+12], a[i+13], a[i+14], a[i+15]);
  1386.         for (j=0; j < strlen(outtext); j++)
  1387.             outtext[j] = toupper(outtext[j]);
  1388.         outcount = strlen(outtext);
  1389.         rc = FSWrite(fnum, &outcount, outtext);
  1390.         if (rc != 0) return(rc);
  1391.         }
  1392.     }
  1393. if (extrawords > 0) {
  1394.     strcpy(outtext, "$\"");
  1395.     for (j = 0; j < extrawords; j++) {
  1396.         if (j > 0) strcat(outtext, " ");
  1397.         sprintf(wordbuff, "%02x%02x %02x%02x", a[i], a[i+1], a[i+2], a[i+3]);
  1398.         strcat(outtext, wordbuff);
  1399.         i += 4;
  1400.         }
  1401.     strcat(outtext, "\"\n");
  1402.     for (j=0; j < strlen(outtext); j++)
  1403.         outtext[j] = toupper(outtext[j]);
  1404.     outcount = strlen(outtext);
  1405.     rc = FSWrite(fnum, &outcount, outtext);
  1406.     if (rc != 0) return(rc);
  1407.     }
  1408. return(0);
  1409. }
  1410.  
  1411. writersc(new)
  1412. unsigned char new;
  1413. {
  1414. Point where;
  1415. ProcPtr dlgHook, fileFilter;
  1416. char * prompt;
  1417. SFReply reply;
  1418. short numTypes;
  1419. SFTypeList typeList;
  1420. OSErr rc;
  1421. unsigned char errtext[256];
  1422. short currvol, rfile;
  1423. Handle temph;
  1424. short i, newnum, resid, rescount;
  1425. ResType restype;
  1426. unsigned char resname[256];
  1427. char resexists;
  1428. Size mapsize;
  1429. unsigned char * sourceptr, *destptr;
  1430. unsigned short resattr;
  1431.  
  1432. if (new) {                /* create new file */
  1433.     where = sfppoint;
  1434.     dlgHook = 0;
  1435.     SFPutFile(&where, "New resource file:",
  1436.               mapname, dlgHook, &reply);
  1437.     if (reply.good == 0) return;
  1438.     p2cstr(&reply.fName);
  1439.     rc = FSDelete(&reply.fName, reply.vRefNum);        /* delete existing file */
  1440.     rc = Create(&reply.fName, reply.vRefNum, 'GFKM', 'GFKB');
  1441.     if (rc != 0) {
  1442.         sprintf(errtext, "Error %d creating output file.", rc);
  1443.         showerr(errtext);
  1444.         return;
  1445.         }
  1446.     }
  1447. else {                    /* get existing resource file */
  1448.     where = sfgpoint;
  1449.     prompt = 0;
  1450.     dlgHook = 0;
  1451.     fileFilter = 0;
  1452.     numTypes = 2;
  1453.     typeList[0] = 'APPL';
  1454.     typeList[1] = 'GFKB';
  1455.     SFGetFile(&where, prompt, fileFilter, numTypes,
  1456.         typeList, dlgHook, &reply);
  1457.     if (reply.good == 0) return;    /* user selected "cancel" */
  1458.     p2cstr(&reply.fName);
  1459.     }
  1460.     
  1461. /* the file we want to open is defined by reply.fName and reply.vRefNum */
  1462.  
  1463. GetVol(errtext, &currvol);
  1464. SetVol(0L, reply.vRefNum);
  1465. rfile = OpenResFile(&reply.fName);
  1466. newnum = 0;        
  1467. resexists = 0;
  1468. if (rfile != -1) {
  1469.     rescount = CountResources('GFKB');
  1470.     if (rescount > 0) {
  1471.         for (i=1; i <= rescount; i++) {
  1472.             SetResLoad(0);            /* don't load resources */
  1473.             temph = GetIndResource('GFKB', i);
  1474.             SetResLoad(0x101);        /* restore loading */
  1475.             if (HomeResFile(temph) != rfile) break;
  1476.             GetResInfo(temph, &resid, &restype, resname);
  1477.             if (EqualString(resname, mapname, 0, 0x101) != 0) {
  1478.                 resexists = 1;
  1479.                 break;
  1480.                 }
  1481.             else {
  1482.                 if (resid > newnum) newnum = resid;
  1483.                 }
  1484.             }
  1485.         }
  1486.     }
  1487.  
  1488. if (resexists) newnum = resid;
  1489. else {
  1490.     if (newnum < 128) newnum = 128;
  1491.     else newnum++;
  1492.     }
  1493.  
  1494. if (resexists) {
  1495.     UseResFile(myresfile);
  1496.     rc = replacedlg(resname);
  1497.     UseResFile(rfile);
  1498.     if (rc) {
  1499.         RmveResource(temph);
  1500.         if (rc = ResError()) {
  1501.             CloseResFile(rfile);
  1502.             SetVol(0L, currvol);
  1503.             sprintf(errtext, "Error %d deleting resource from file", rc);
  1504.             showerr(errtext);
  1505.             return;
  1506.             }
  1507.         }
  1508.     else {
  1509.         CloseResFile(rfile);
  1510.         SetVol(0L, currvol);
  1511.         return;
  1512.         }
  1513.     }
  1514. if (rfile != -1) CloseResFile(rfile);
  1515.  
  1516. CreateResFile(&reply.fName);
  1517. rfile = OpenResFile(&reply.fName);
  1518. if (rfile == -1) {
  1519.     SetVol(0L, currvol);
  1520.     sprintf(errtext, "Error %d opening resource file", ResError());
  1521.     showerr(errtext);
  1522.     return;
  1523.     }
  1524.     
  1525. /* get handle to data to write out */
  1526. mapsize = sizeof(keybuffn);
  1527. mapsize += sizeof(keybuffs);
  1528. mapsize += sizeof(keybuffc);
  1529. mapsize += sizeof(keybuffcs);
  1530. mapsize += sizeof(keybuffo);
  1531. mapsize += sizeof(ascbuffn);
  1532. mapsize += sizeof(ascbuffs);
  1533. mapsize += sizeof(ascbuffc);
  1534. mapsize += sizeof(ascbuffcs);
  1535. mapsize += sizeof(ascbuffo);
  1536. mapsize += sizeof(hexmap) * hexcount;
  1537. temph = NewHandle(mapsize);
  1538. if (temph == 0) {
  1539.     CloseResFile(rfile);
  1540.     SetVol(0L, currvol);
  1541.     sprintf(errtext, "Out of memory allocating resource");
  1542.     showerr(errtext);
  1543.     return;
  1544.     }
  1545.  
  1546. destptr = *temph;
  1547.  
  1548. sourceptr = keybuffn;
  1549. memcpy(destptr, sourceptr, sizeof(keybuffn));
  1550. destptr += sizeof(keybuffn);
  1551.  
  1552. sourceptr = keybuffs;
  1553. memcpy(destptr, sourceptr, sizeof(keybuffs));
  1554. destptr += sizeof(keybuffs);
  1555.  
  1556. sourceptr = keybuffc;
  1557. memcpy(destptr, sourceptr, sizeof(keybuffc));
  1558. destptr += sizeof(keybuffc);
  1559.  
  1560. sourceptr = keybuffcs;
  1561. memcpy(destptr, sourceptr, sizeof(keybuffcs));
  1562. destptr += sizeof(keybuffcs);
  1563.  
  1564. sourceptr = keybuffo;
  1565. memcpy(destptr, sourceptr, sizeof(keybuffo));
  1566. destptr += sizeof(keybuffo);
  1567.  
  1568. sourceptr = ascbuffn;
  1569. memcpy(destptr, sourceptr, sizeof(ascbuffn));
  1570. destptr += sizeof(ascbuffn);
  1571.  
  1572. sourceptr = ascbuffs;
  1573. memcpy(destptr, sourceptr, sizeof(ascbuffs));
  1574. destptr += sizeof(ascbuffs);
  1575.  
  1576. sourceptr = ascbuffc;
  1577. memcpy(destptr, sourceptr, sizeof(ascbuffc));
  1578. destptr += sizeof(ascbuffc);
  1579.  
  1580. sourceptr = ascbuffcs;
  1581. memcpy(destptr, sourceptr, sizeof(ascbuffcs));
  1582. destptr += sizeof(ascbuffcs);
  1583.  
  1584. sourceptr = ascbuffo;
  1585. memcpy(destptr, sourceptr, sizeof(ascbuffo));
  1586. destptr += sizeof(ascbuffo);
  1587.  
  1588. sourceptr = hexbuff;
  1589. memcpy(destptr, sourceptr, sizeof(hexmap) * hexcount);
  1590.  
  1591. /* Add the new resource (finally!) */
  1592.  
  1593. AddResource(temph, 'GFKB', newnum, mapname);
  1594. if (rc = ResError()) {
  1595.     CloseResFile(rfile);
  1596.     SetVol(0L, currvol);
  1597.     sprintf(errtext, "Error %d adding resource to file", rc);
  1598.     showerr(errtext);
  1599.     return;
  1600.     }
  1601.  
  1602. resattr = GetResAttrs(temph);
  1603. if (rc = ResError()) {
  1604.     CloseResFile(rfile);
  1605.     SetVol(0L, currvol);
  1606.     sprintf(errtext, "Error %d getting resource attributes", rc);
  1607.     showerr(errtext);
  1608.     return;
  1609.     }
  1610.  
  1611. resattr |= resPreload;
  1612.  
  1613. SetResAttrs(temph, resattr);
  1614. if (rc = ResError()) {
  1615.     CloseResFile(rfile);
  1616.     SetVol(0L, currvol);
  1617.     sprintf(errtext, "Error %d setting resource attributes", rc);
  1618.     showerr(errtext);
  1619.     return;
  1620.     }
  1621.  
  1622. CloseResFile(rfile);
  1623. if (rc = ResError()) {
  1624.     sprintf(errtext, "Error %d closing resource to file", rc);
  1625.     showerr(errtext);
  1626.     }
  1627. SetVol(0L, currvol);
  1628. return;
  1629. }
  1630.  
  1631. replacedlg(resname)
  1632. unsigned char * resname;
  1633. {
  1634. DialogPtr dlgptr;
  1635. DialogPeek dStorage;
  1636. WindowPtr behind;
  1637. unsigned short (*filterProc) ();
  1638. short itemHit;
  1639. Handle version;
  1640. short gtype;
  1641. Handle gitem;
  1642. Rect gbox;
  1643. static char nullstr[1] = {0};
  1644.  
  1645. dStorage = 0;
  1646. behind = (WindowPtr)-1;
  1647. ParamText(resname, nullstr, nullstr, nullstr);
  1648. dlgptr = GetNewDialog(258, dStorage, behind);
  1649. ctrwindow(dlgptr);
  1650. ShowWindow(dlgptr);
  1651.  
  1652. /* frame the default selection */
  1653. framedflt(dlgptr);
  1654.  
  1655. filterProc = 0;
  1656. ModalDialog(filterProc, &itemHit);
  1657. DisposDialog(dlgptr);
  1658. ParamText(nullstr, nullstr, nullstr, nullstr);
  1659. if (itemHit == 2) return(1);
  1660. else return(0);
  1661. }
  1662.  
  1663. showinfo()
  1664. {
  1665. DialogPtr dlgptr;
  1666. DialogPeek dStorage;
  1667. WindowPtr behind;
  1668. unsigned short (*filterProc) ();
  1669. short itemHit;
  1670. Handle version;
  1671. short gtype;
  1672. Handle gitem;
  1673. Rect gbox;
  1674. static char nullstr[1] = {0};
  1675. unsigned char numtext[32];
  1676. unsigned char datestr[516];
  1677. short datelen;
  1678. FileParam fp;
  1679.  
  1680. fp.ioNamePtr = &defreply.fName;
  1681. fp.ioVRefNum = defreply.vRefNum;
  1682. fp.ioFVersNum = 0;
  1683. fp.ioFDirIndex = 0;
  1684. PBGetFInfo(&fp, 0);
  1685. IUDateString(fp.ioFlMdDat, 2, datestr);
  1686. strcat(datestr, "  ");
  1687. datelen = strlen(datestr);
  1688. IUTimeString(fp.ioFlMdDat, 1, datestr+datelen);
  1689.  
  1690. sprintf(numtext, "%d", mapnum);
  1691.  
  1692. p2cstr(&defreply.fName);
  1693. ParamText(&defreply.fName, datestr, mapname, numtext);
  1694. c2pstr(&defreply.fName);
  1695. dStorage = 0;
  1696. behind = (WindowPtr)-1;
  1697. dlgptr = GetNewDialog(259, dStorage, behind);
  1698. ctrwindow(dlgptr);
  1699. ShowWindow(dlgptr);
  1700.  
  1701. /* frame the default selection */
  1702. framedflt(dlgptr);
  1703.  
  1704. filterProc = 0;
  1705. ModalDialog(filterProc, &itemHit);
  1706. DisposDialog(dlgptr);
  1707. ParamText(nullstr, nullstr, nullstr, nullstr);
  1708. }
  1709.  
  1710.  
  1711.  
  1712.